package com.swc.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

import com.swc.constant.HeaderConstant;
import com.swc.property.SecretKeyProperty;
import com.swc.wrapper.DecryptJsonReqParamWrapper;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * 解密json请求的参数
 * @author huyupeng
 * @date 2020-09-18
 */
@Component
public class DecryptJsonReqParamFilter extends ZuulFilter {

    private Logger logger = LoggerFactory.getLogger(DecryptReqParamFilter.class);

    @Autowired
    private SecretKeyProperty rsaKeyProperty;

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER + 1;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        return isEntryFilter(request);
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String secretKey = ctx.getRequest().getHeader(HeaderConstant.HEADER_SECRET_KEY);
        if (StringUtils.isEmpty(secretKey)) {
            throw new RuntimeException("请求头中没有密钥");
        }
        DecryptJsonReqParamWrapper jsonRequestWrapper = new DecryptJsonReqParamWrapper(request, rsaKeyProperty);
        ctx.setRequest(jsonRequestWrapper);
        return null;
    }

    /**
     * 是否进入该过滤器
     * 条件：不是get请求 && 请求头中包含 application/json && 需要对数据进行解密
     * @param request
     * @return
     */
    public boolean isEntryFilter(HttpServletRequest request) {
        String encryptMode = request.getHeader(HeaderConstant.HEADER_ENCRYPT_MODE);
        String contentType = request.getContentType();
        if (!"get".equalsIgnoreCase(request.getMethod()) && StringUtils.isNotEmpty(contentType)
                && StringUtils.isNotEmpty(encryptMode) && !HeaderConstant.HEADER_ENCRYPT_MODE_NONE.equals(encryptMode)
                && MediaType.APPLICATION_JSON_VALUE.contains(request.getContentType())) {
            return true;
        }
        return false;
    }

}